package com.xz.queue;

import com.xz.bean.Actress;
import com.xz.bean.Arzon;
import com.xz.bean.LinkReg;
import com.xz.dao.ArzonDao;
import com.xz.http.instance.BerkeleyDBSingleton;
import com.xz.http.instance.ClientSingleton;
import com.xz.http.instance.HttpFactory;
import com.xz.service.ArzonService;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.BlockingQueue;

/**
 * Created by YLZX-Z0107 on 2014/7/20.
 */
public class Producer implements Runnable {
    //    Set<String> details = new HashSet<String>(1000);  //使用set做数据排重，毕竟不是长久之计
    ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
    ArzonService arzonService = (ArzonService) ac.getBean("arzonService");
    BerkeleyDBSingleton berkeley = BerkeleyDBSingleton.getInstance();

    public Producer(BlockingQueue<String> urls) {
        this.urls = urls;
    }

    @Override
    public void run() {
        CloseableHttpClient client = ClientSingleton.getInstance().getClient();
        HttpGet get = HttpFactory.getMethod();
        System.out.println("开启生产线程. queue size: " + urls.size());
        get.addHeader("Cookie", "PHPSESSID=go95798enia09k0vcc6k9ao3n0");
        while (!urls.isEmpty()) {
            try {
                sleep();
                String url = urls.take();
                if (berkeley.add(url)) {
                    setUri(get, url);
                    String content = getResponseContent(client, get);
                    if (StringUtils.isNotEmpty(content)) {
                        Document document = Jsoup.parse(content);
                        Elements elements = document.select("a[href]");
                        LinkReg reg = new LinkReg();
                        reg.setLinkCon("item_");
                        reg.setLinkUnCon("mailto");
                        for (Element element : elements) {
                            if (isCorrect(element, reg)) {
                                String detail = element.attr("href");
                                if (urls.size() < 500 && berkeley.has(getAbsUrl(detail))) {
                                    urls.put(getAbsUrl(detail));
                                }
                            }
                        }
                        saveArzon(document, url);
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("生产,queue size: " + urls.size());
        }

    }

    private void saveArzon(Document document, String url) {
        Element title = document.select("div.detail_title>h1").first();
        Element cover = document.select("td.img>div>a").first();
        Arzon arzon = new Arzon();
        arzon.setUrl(url);
        arzon.setTitle(title.text().trim());
        arzon.setCover(cover.attr("href"));
        Elements basic = document.select("table.item>tbody>tr");
        for (Element element : basic) {
            if (element.text().contains(Arzon.ACTRESS)) {
                if (StringUtils.isNotEmpty(element.text().replace(Arzon.ACTRESS, "").trim())) {
                    String[] acts = element.text().replace(Arzon.ACTRESS, "").trim().split(" ");
                    List<Actress> actresses = new ArrayList<Actress>();
                    for (String actress : acts) {
                        actresses.add(new Actress(actress));
                    }
                    arzon.setActresses(actresses);
                }
            }
            if (element.text().contains(Arzon.FACTORY)) {
                String factory = element.text().replace(Arzon.FACTORY, "").trim();
                if (StringUtils.isNotEmpty(factory)) {
                    arzon.setFactory(factory);
                }
            }
            if (element.text().contains(Arzon.SERIES)) {
                String series = element.text().replace(Arzon.SERIES, "").trim();
                if (StringUtils.isNotEmpty(series)) {
                    arzon.setSeries(series);
                }
            }
            if (element.text().contains(Arzon.OFFER_DATE)) {
                String offerDate = element.text().replace(Arzon.OFFER_DATE, "").replace(Arzon.REPLACE_DVD, "").trim();
                SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
                Date date;
                try {
                    date = format.parse(offerDate);
                } catch (ParseException e) {
                    date = new Date();
                }
                arzon.setOfferDate(date);
            }
            if (element.text().contains(Arzon.FAN_HAO)) {
                String fan = element.text().replace(Arzon.FAN_HAO, "").replace(Arzon.REPLACE_FAN, "").replace("　", "").replace(" ", "").trim();
                arzon.setFan(fan);
            }
        }
        Elements images = document.select("div#sample_image>a");
        List<String> imageList = new ArrayList<String>();
        for (Element element : images) {
            imageList.add(element.attr("href"));
        }
        arzon.setImages(imageList);
        arzonService.saveArzon(arzon);
    }

    public static void setUri(HttpGet get, String uri) {
        try {
            get.setURI(new URI(uri));
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }

    private void sleep() {
        try {
            Thread.sleep(DEFAULT_SLEEP);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static boolean isCorrect(Element element, LinkReg reg) {
        boolean cur = true;
        if (reg != null && reg.getLinkUnCon() != null) {
            String[] linkUnCon = reg.getLinkUnCon().split(",");
            for (String link : linkUnCon) {
                if (element.attr("href").contains(link)) {
                    return false;
                }
            }
        }
        if (reg != null && reg.getLinkCon() != null) {
            String[] linkCon = reg.getLinkCon().split(",");
            for (String link : linkCon) {
                if (!element.attr("href").contains(link)) {
                    return false;
                }
            }
        }
        if (StringUtils.isEmpty(element.text())) {
            return false;
        }
        return cur;
    }

    public static String getAbsUrl(String url) {
        if (url.indexOf("/") == 0) {
            return "http://www.arzon.jp" + url;
        }
        return url;
    }

    public String getResponseContent(CloseableHttpClient client, HttpRequestBase method) {
        String result = null;
        try {
            CloseableHttpResponse response = client.execute(method);
            result = EntityUtils.toString(response.getEntity(), "utf-8");
            if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                System.out.println("get error!");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    private BlockingQueue<String> urls;
    private int DEFAULT_SLEEP = 200;
}
